class Promise{
    constructor(executor){
        this.status='pending';  //默认的状态
        this.value=undefined;   //默认成功的值
        this.reason=undefined;  //默认失败的原因
        this.onResolvedCallbacks=[];//存放成功的数组
        this.onRejectedCallbacks=[];//存放失败的数组
        let resolve=(value)=>{
            if(this.status==='pending'){
                this.status='resolved';//成功了 
                this.value=value;
                this.onResolvedCallbacks.forEach(fn=>fn());
                // for(let i=0;i<this.onResolvedCallbacks.length;i++){
                //     this.onResolvedCallbacks[i]();
                // }
            }
        }
        let reject=(reason)=>{
            if(this.status==='pending'){
                this.status='rejected';//失败了
                this.reason=reason;
                this.onRejectedCallbacks.forEach(fn=>fn());
            }
        }
        try {//捕获异常
            executor(resolve,reject);//默认让执行器执行
        } catch (e) {
            reject(e)
        }    
    }
    then(onFufilled,onRejected){
        //解决onFufilled或onRejected没有传的问题
        onFufilled=typeof onFufilled==='function'?onFufilled:d=>d;
        onRejected=typeof onRejected==='function'?onRejected:e=>{throw e};
        let promise2;
        if(this.status==='resolved'){
            promise2=new Promise((resolve,reject)=>{
                setTimeout(() => {
                    try{
                        let x=onFufilled(this.value);
                        //判断p是不是一个promise，如果是取它的结果作为promise2成功的结果，
                        //如果返回一个普通值，同样作为promise2成功的结果
                        resolvePromise(promise2,x,resolve,reject);//解析p和promise2之间的关系  
                    }catch(e){
                        reject(e);
                    }           
                }, 0);

            });
        }
        if(this.status==='rejected'){
            promise2=new Promise((resolve,reject)=>{
                setTimeout(() => {
                    try{
                        let x=onRejected(this.reason);
                        resolvePromise(promise2,x,resolve,reject);  
                    }catch(e){
                        reject(e);
                    }                 
                }, 0);
            })
        }
        if(this.status==='pending'){//当前既没有成功，也没有失败
            promise2=new Promise((resolve,reject)=>{
                this.onResolvedCallbacks.push(()=>{//存放成功的回调
                    setTimeout(() => {
                        try{
                            let x=onFufilled(this.value);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }                        
                    }, 0);
                });
                this.onRejectedCallbacks.push(()=>{//存放失败的回调
                    setTimeout(() => {
                        try{
                            let x=onRejected(this.reason);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }                     
                    }, 0);
                })
            })
            // return promise2;
        }
        return promise2;//调用then后返回一个新的promise
    }
    catch(fn){
      return this.then(null,fn);
    }
}

Promise.all = (promises) => {
    return new Promise((resolve, reject) => {
        let result = [];
        let index = 0;
        let processData = (key, y) => {
            index++
            result[key] = y;
            if (promises.length === index) {
            resolve(result);
            }
        }
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(y => {
                processData(i, y);
            }, reject);
        }
    })
}

Promise.resolve=function(val){
    return new Promise((resolve,reject)=>{
        resolve(val)
    })
}
Promise.reject=function(val){
    return new Promise((resolve,reject)=>{
        reject(val)
    })
}

//实现多套promise共用
function resolvePromise(promise2,x,resolve,reject){
    //判断x是不是promise
    if(promise2===x){//如果当前返回的promise和x引用同一个对象报类型错误(不能自己等待自己完成)
        return reject(new TypeError('循环引用'));
    }
    //x不是null并且是对象或函数，可能是promise
    if(x!==null&&(typeof x==='object'|| typeof x==='function')){
        let called; //标识当前promise有没有调用过
        try{//尽量让别人瞎写,防止取then时出现异常
            let then=x.then;//取x的then看是不是函数
            if(typeof then==='function'){//如果是函数就认为它是promise
                then.call(x,(y)=>{//第一个参数是this，后面的是成功的回调和失败的回调
                    if(called) return;
                    called=true;
                    //如果y是promise继续递归解析
                    resolvePromise(promise2,y,resolve,reject);
                },(err)=>{//只要有一个失败了就失败了
                    if(called) return;
                    called=true;
                    reject(err);
                })
            }else{//then是一个普通对象直接成功
               resolve(x);
            }
        }catch(e){
            if(called) return;
            called=true;
            reject(e);
        }      
    }else{//如果x是普通值直接成功
        resolve(x);
    }
}

//promise的语法糖,可以同它来做测试
/* Promise.defer=Promise.deferred=function(){
    let dfd={};
    dfd.promise=new Promise((resolve,reject)=>{
        dfd.resolve=resolve;
        dfd.reject=reject;
    })
    return dfd;
}
module.exports=Promise; */
//npm install promises-aplus-tests -g
//promises-aplus-tests 文件名


let p = new Promise((res,rej)=>{
	res("不会延迟的状态")
}).then((value)=>{
	console.log(value);
	return  new Promise((res,rej)=>{
		res("链式调用")
	}); 
}).then(value=>{
	console.log(value)
	return  new Promise((res,rej)=>{
		res("链式调用2")
	}); 
})
p.then((value)=>{
	console.log(value+"2");})